import json
import logging
from datetime import datetime, timedelta

from dateutil.relativedelta import relativedelta

from credit_voice_service.dialogue.factory.base_info.strategy.base_info_strategy import BaseInfoStrategy


def get_low_interest_strength(beforeCutRate, currentRate):
    low_interest_strength = ''
    try:
        if beforeCutRate and currentRate and beforeCutRate != currentRate:
            if beforeCutRate == '0.00065以上':
                return low_interest_strength
            else:
                beforeCutRate_nums = beforeCutRate.split('~')[-1].strip()
                currentRate_nums = currentRate.split('~')[-1].strip()
                low_interest_strength = str(int(float(beforeCutRate_nums) * 100000)) + '到' + str(
                    int(float(currentRate_nums) * 100000))
        if beforeCutRate and currentRate and beforeCutRate == currentRate:
            low_interest_strength = '降息前后一致'
    except Exception as e:
        logging.error("获取用户降息力度报错:{} ".format(str(e)))
    finally:
        return low_interest_strength


def get_withdrawal_strength(tradePrice):
    withdrawal_strength = ''
    try:
        if tradePrice:
            ranges = [
                (0, 9999, '提升一万内'),
                (10000, 15999, '提升一万多'),
                (16000, 19999, '提升近两万'),
                (20000, 25999, '提升两万多'),
                (26000, 29999, '提升近三万'),
                (30000, 35999, '提升三万多'),
                (36000, 39999, '提升近四万'),
                (40000, 45999, '提升四万多'),
                (46000, 49999, '提升近五万'),
                (50000, 55999, '提升五万多'),
                (56000, 59999, '提升近六万'),
                (60000, 65999, '提升六万多'),
                (66000, 69999, '提升近七万'),
                (70000, 75999, '提升七万多'),
                (76000, 79999, '提升近八万'),
                (80000, 85999, '提升八万多'),
                (86000, 89999, '提升近九万'),
                (90000, 95999, '提升九万多'),
                (96000, 99999, '提升近十万'),
                (100000, 100000, '提升十万'),
                (100001, float('inf'), '提升十万以上'),
            ]
            for lower, upper, name in ranges:
                if lower <= int(float(tradePrice)) <= upper:
                    withdrawal_strength = name
                    break
    except Exception as e:
        logging.error('获取用户提升额度报错 报错信息:{}'.format(str(e)))
    finally:
        return withdrawal_strength


def get_amount_data(total_amount, rest_amount):
    total_amount_data = ''
    rest_amount_data = ''
    try:
        if total_amount:
            # if '+∞' in total_amount:
            #     left, right = total_amount.split('-')
            #     if int(left) > 100000:
            #         total_amount_data = '总额度超10万'
            #     else:
            #         total_amount_data = '总额度近10万'
            # else:
            #     left, right = map(int, total_amount.split('-'))
            #     if right > 100000:
            #         total_amount_data = '总额度超10万'
            #     else:
            #         total_amount_data = '总额度近10万'
            total_amount_data = '总额度{}'.format(total_amount)
        if rest_amount:
            position = rest_amount.find('-')
            if position == 0:
                rest_amount_data = '可用额度为负'
            else:
                rest_amount_data = '可用额度{}'.format(rest_amount)
    except Exception as e:
        logging.error('获取用户总额度和可用额度报错:{}'.format(str(e)))
    finally:
        return total_amount_data, rest_amount_data


def get_user_min_average(orderListJson):
    user_min_average = 0
    try:
        if orderListJson:
            six_months_ago = datetime.now().replace(day=1, hour=0, minute=0, second=0,
                                                    microsecond=0) - relativedelta(months=7)
            filtered_data = [item for item in orderListJson if
                             datetime.strptime(item['loanDateTime'], '%Y年%m月') > six_months_ago]
            if filtered_data:
                # 计算每个订单的平均值并找出最小的平均值
                min_average = float('inf')
                for d in filtered_data:
                    try:
                        if '+∞' in d['orderAmount']:
                            left, right = d['orderAmount'].split('-')
                            average = int(left)
                            if average < min_average:
                                min_average = average
                        else:
                            left, right = map(int, d['orderAmount'].split('-'))
                            average = (left + right) / 2
                            if average < min_average:
                                min_average = average
                    except:
                        continue

                # 如果没有符合条件的订单，那么最小平均值为0
                min_average = min_average if min_average != float('inf') else 0
                user_min_average = int(min_average)
    except Exception as e:
        logging.error('获取用户总额度和可用额度报错:{}'.format(str(e)))
    finally:
        return user_min_average


def get_available_limit(restAmount, user_min_average):
    available_limit = ''
    try:
        if restAmount:
            position = restAmount.find('-')
            if position == 0:
                available_limit = '没有额度'
            else:
                if '+∞' in restAmount:
                    left, right = restAmount.split('-')
                    rest_average = int(left)
                else:
                    left, right = map(int, restAmount.split('-'))
                    rest_average = (left + right) / 2
                if rest_average <= 500:
                    available_limit = '没有额度'
                else:
                    if user_min_average == 0:
                        if rest_average >= 30000:
                            available_limit = ''
                        else:
                            available_limit = ''
                    else:
                        if rest_average > user_min_average or rest_average >= 30000:
                            available_limit = ''
                        else:
                            available_limit = '额度不够'
    except Exception as e:
        logging.error('获取用户总额度和可用额度报错:{}'.format(str(e)))
    finally:
        return available_limit


def get_call_count(session_id):
    call_count = ''
    data = session_id.split('-')
    task_id = data[4]
    if "1259" == task_id:
        call_count = '2-call'
    elif "1597" == task_id:
        call_count = '3-call'
    return call_count


def get_user_stage(batch_id):
    user_stage = ''
    if '成长期' in batch_id:
        user_stage = '成长期'
    elif '成熟期' in batch_id:
        user_stage = '成熟期'
    return user_stage


def get_now_cut_rate(low_interest, beforeCutRate, currentRate):
    now_cut_rate = ''
    try:
        if beforeCutRate == '0.00065以上':
            now_cut_rate = '降息前费率65'
        elif currentRate == '0.00065以上':
            now_cut_rate = '当前费率65'
        if low_interest:
            currentRate_nums = currentRate.split('~')[-1].strip()
            now_cut_rate = '当前费率{}'.format(str(int(float(currentRate_nums) * 100000)))
        else:
            beforeCutRate_nums = beforeCutRate.split('~')[-1].strip()
            now_cut_rate = '降息前费率{}'.format(str(int(float(beforeCutRate_nums) * 100000)))
    except Exception as e:
        logging.error('获取当前利息报错:{}'.format(str(e)))

    finally:
        return now_cut_rate


def get_not_right(low_interest=False, withdrawal=False, coupon=False):
    not_right = ''
    if low_interest and not withdrawal:
        not_right = '没有提额'
    if not low_interest and withdrawal:
        not_right = '没有降息'
    if not low_interest and not withdrawal and coupon:
        not_right = '没有降息,没有提额'
    return not_right


class BaseInfoStrategy2144(BaseInfoStrategy):

    def get_base_info(self, session_id, user_info):
        # 名字 年龄  优惠券名称 权益 降息幅度 降息剩余天数 拨次 用户阶段 是否有88折券 额度是否可用 是否有提额机会 优惠券剩余天数 降息力度 提额力度 总额度 可用额度 当前利息 没有提额/没有降息
        name = ''
        age = ''
        certificate = ''
        right = '无权益'
        rightCutRate = ''
        cut_rate_day = ''
        call_count = ''
        user_stage = ''
        available_limit = ''
        increase_opportunities = ''
        certificate_name = ''
        certificate_day = ''
        low_interest_strength = ''
        withdrawal_strength = ''
        total_amount_data = ''
        rest_amount_data = ''
        now_cut_rate = ''
        not_right = ''
        try:
            if not user_info:
                return {'用户姓名': name, '用户年龄': age, '初始用户权益': right, '券信息': certificate,
                        '降息幅度': rightCutRate, '降息剩余天数': cut_rate_day, 'call次': call_count,
                        '用户阶段': user_stage, '券名称': certificate_name, '额度是否够用': available_limit,
                        '提额机会': increase_opportunities, '优惠券剩余天数': certificate_day,
                        '降息力度': low_interest_strength, '提额力度': withdrawal_strength,
                        '总额度': total_amount_data, '可用额度': rest_amount_data, '当前利息': now_cut_rate,
                        '是否提额降息': not_right}
            name = user_info.get('fullName', '')
            sex = user_info.get('sexByChineseWord', '')
            if name and sex:
                name = name + sex
            else:
                name = ''
            age = user_info.get('ageRange', '')
            certificate = ''
            low_interest = False
            coupon = False
            withdrawal = False

            couponDetailJson = user_info.get('couponDetailList', '')
            if couponDetailJson:
                couponDetailList = json.loads(couponDetailJson)
                for couponDetail in couponDetailList:
                    activityName = couponDetail.get('activityName', '')
                    if activityName:
                        if '免息' in activityName and '券' in activityName:
                            certificate = activityName
                            break
                        elif '券' in activityName:
                            certificate = activityName
                            continue
                        elif '折息' in activityName:
                            certificate = activityName
                            continue

            cutRateTime = user_info.get('cutRateTime', '')
            try:
                if cutRateTime and '-' != cutRateTime and datetime.strptime(cutRateTime, '%Y-%m-%d'):
                    cutRateTime = datetime.strptime(cutRateTime, '%Y-%m-%d')
                    current_date = datetime.now()
                    days_left = (cutRateTime - current_date).days
                    if days_left >= 0:
                        cutRate = user_info.get('cutRate', '')
                        if cutRate and cutRate == '是':
                            low_interest = True
                            if days_left > 7:
                                cut_rate_day = '降息8天后到期'
                            else:
                                cut_rate_day = '降息{}天到期'.format(days_left)
                        # 降息前
                        beforeCutRate = user_info.get('beforeCutRate', '')
                        # 降息后
                        currentRate = user_info.get('currentRate', '')

                        beforeCutRate = beforeCutRate.replace('-', '')
                        currentRate = currentRate.replace('-', '')
                        low_interest_strength = get_low_interest_strength(beforeCutRate, currentRate)
                        if beforeCutRate and currentRate:
                            # 当前费率是这个 同一都是低
                            if '0.00015 ~ 0.00025' == currentRate:
                                rightCutRate = '利息降到最低'
                            # 当前费率
                            if '0.00025 ~ 0.00035' == currentRate and (
                                    '0.00045 ~ 0.00055' == beforeCutRate or '0.00055 ~ 0.00065' == beforeCutRate):
                                rightCutRate = '利息降幅大'
                            if '0.00035 ~ 0.00045' == currentRate and '0.00055 ~ 0.00065' == beforeCutRate:
                                rightCutRate = '利息降幅大'

            except Exception:
                logging.error('日期转换错误')
            try:
                # 降息前
                beforeCutRate = user_info.get('beforeCutRate', '')
                # 降息后
                currentRate = user_info.get('currentRate', '')
                now_cut_rate = get_now_cut_rate(low_interest, beforeCutRate, currentRate)
            except Exception:
                logging.error('获取当前利息报错')

            couponName = user_info.get('couponName', '')
            if couponName or certificate:
                coupon = True

            try:
                tradeTime = user_info.get('tradeTime', '')
                if tradeTime and datetime.strptime(tradeTime, '%Y-%m-%d'):
                    withdrawal = True
                    tradePrice = user_info.get('tradePrice', '')
                    withdrawal_strength = get_withdrawal_strength(tradePrice)
            except Exception:
                logging.error('日期转换错误')

            try:
                batchId = user_info.get('batchId', '')
                user_stage = get_user_stage(batchId)
            except Exception:
                logging.error('批次获取错误')

            try:
                call_count = get_call_count(session_id)
            except Exception:
                logging.error('获取Call次报错')

            try:
                couponListJson = user_info.get('couponList', '')
                certificate_day_int = None
                if couponListJson:
                    for couponDetail in couponListJson:
                        couponDetailName = couponDetail.get('couponName', '')
                        endDate = couponDetail.get('endDate', '')
                        try:
                            endDateDay = datetime.fromtimestamp(endDate / 1000)
                            current_date = datetime.now()
                            days_left = (endDateDay - current_date).days
                            if certificate_day_int is None:
                                certificate_day_int = days_left
                            else:
                                if (days_left >= 0 and '88折' in couponDetailName) or (
                                        days_left >= 0 and '85折' in couponDetailName):
                                    certificate_day_int = days_left
                                elif 0 <= days_left < certificate_day_int:
                                    certificate_day_int = days_left
                        except Exception:
                            logging.error("优惠券结束日期转移报错")
                        if '88折' in couponDetailName:
                            certificate_name = '0元88折息费活动券'
                            break
                        if '85折' in couponDetailName:
                            certificate_name = '0元85折息费活动券'
                            break

                if certificate_day_int is not None and certificate_day_int <= 6:
                    certificate_day = '优惠券{}天到期'.format(certificate_day_int)
                elif certificate_day_int is not None and certificate_day_int > 7:
                    certificate_day = '优惠券7天到期'
                elif certificate:
                    certificate_day = '优惠券7天到期'

                if not certificate_name:
                    if certificate and '88折' in certificate:
                        certificate_name = '0元88折息费活动券'
                    if certificate and '85折' in certificate:
                        certificate_name = '0元85折息费活动券'
            except Exception:
                logging.error("获取用户是否持有88折券报错")

            try:
                orderListJson = user_info.get('orderList', '')
                user_min_average = get_user_min_average(orderListJson)
                totalAmount = user_info.get('totalAmount', '')
                restAmount = user_info.get('restAmount', '')
                total_amount_data, rest_amount_data = get_amount_data(totalAmount, restAmount)
                available_limit = get_available_limit(restAmount, user_min_average)
            except Exception:
                logging.error("获取额度是否够用报错")
            try:
                jinPromote = user_info.get('jinPromote', '')
                if jinPromote and '符合要求' == jinPromote:
                    increase_opportunities = '主动提额资格'
            except Exception:
                logging.error("获取额度是否够用报错")

            rightList = list()
            if low_interest:
                rightList.append('已获得降息')
            if withdrawal:
                rightList.append('已获得提额')
            if coupon:
                rightList.append('已获得优惠券')
            if not rightList:
                rightList.append('无权益')
            not_right = get_not_right(low_interest, withdrawal, coupon)
            right = ','.join(rightList)

        except Exception as e:
            logging.error("获取用户信息报错 报错信息:{} session_id:{}".format(str(e), session_id))
        finally:
            return {'用户姓名': name, '用户年龄': str(age), '初始用户权益': right, '券信息': certificate,
                    '降息幅度': rightCutRate, '降息剩余天数': cut_rate_day, 'call次': call_count,
                    '用户阶段': user_stage, '券名称': certificate_name, '额度是否够用': available_limit,
                    '提额机会': increase_opportunities, '优惠券剩余天数': certificate_day,
                    '降息力度': low_interest_strength, '提额力度': withdrawal_strength,
                    '总额度': total_amount_data, '可用额度': rest_amount_data, '当前利息': now_cut_rate,
                    '是否提额降息': not_right}


if __name__ == '__main__':
    base_info = BaseInfoStrategy2144()
    user_info = {}
    print(base_info.get_base_info('1', user_info))
